package com.beiding.natgo.client;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

@Slf4j
public class ChanelHolder {
    private String id;

    //读写分离
    private final ByteBuffer byteBuffer;
    private final ByteBuffer writeByteBuffer;
    private SocketChannel socketChannel;
    private SelectionKey selectionKey;
    private SessionHolder sessionHolder;

    private ClientWorker clientWorker;

    public ChanelHolder(ClientWorker clientWorker, SocketChannel socketChannel, SessionHolder sessionHolder,String id) {
        this.clientWorker = clientWorker;
        this.sessionHolder = sessionHolder;
        this.socketChannel = socketChannel;
        this.id = id;
        byteBuffer = ByteBuffer.allocateDirect(1024);
        writeByteBuffer = ByteBuffer.allocateDirect(1024);
    }

    public void setSelectionKey(SelectionKey selectionKey) {
        this.selectionKey = selectionKey;
    }

    public SelectionKey getSelectionKey() {
        return selectionKey;
    }

    public String getId() {
        return id;
    }

    public ByteBuffer getByteBuffer() {
        return byteBuffer;
    }

    public SocketChannel getSocketChannel() {
        return socketChannel;
    }

    //读写 发生在一个线程中
    void handleRead() {
        while (true) {
            byteBuffer.clear();
            try {
                //读取数据并发送到客户端
                int read = socketChannel.read(byteBuffer);
                if (read == 0) {
               //     log.info("消息读取结束");
                    break;
                }
                if (read < 0) {//连接已经断开
                    log.info("客户端连接关闭{}",id);
                    selectionKey.cancel();
                    clientWorker.removeChanelAndSendClose(this.id);
                    break;
                }
                byteBuffer.flip();
                byte[] bytes = new byte[byteBuffer.remaining()];
                byteBuffer.get(bytes);
                sessionHolder.sendData(this.id, bytes);
            } catch (IOException e) {
                selectionKey.cancel();
                clientWorker.removeChanelAndSendClose(this.id);
                e.printStackTrace();
                break;
            }
        }
    }

    //由其他线程写入
    public void writeData(byte[] data) {
        try {
            ByteBuffer byteBuffer = ByteBuffer.wrap(data);
            socketChannel.write(byteBuffer);
        } catch (IOException e) {
            selectionKey.cancel();
            clientWorker.removeChanelAndSendClose(this.id);
            e.printStackTrace();
        }
    }

}
